#include "cmdline.h"
#include "nstring.h"
#include "tokenizer.h"


static char *arg_strdup(const char *str)             // pl. "hello bello" -> hello bello
{
    if (str == NULL)
        return NULL;

    int real_len = (int)strlen(str);
    int len = real_len;

    if (str[0] == '\"')
        len--;

    if (str[real_len - 1] == '\"')
        len--;

    char *res = (char*)malloc(len + 1);

    memcpy(res, str[0] == '\"' ? (str+1) : str, len);
    res[len] = '\0';

    return res;
}


CCmdlineArgs::CCmdlineArgs()
{
    argc = 0;
    argv = NULL;
}


void CCmdlineArgs::Init(const char *cmdline)
{    
    Cleanup();

    CTokenizer t;
    const CChString *token = &t.GetTokenPtr()->token;

    t.OpenMem((uint8_t*)cmdline, strlen(cmdline), /*CTokenizer::DONTREMOVEQUOTE |*/ CTokenizer::QUOTEDWORD);

    try
    {
        // megszamoljuk, hany argumentum van

        while (t.Next(false))
            argc++;

        t.Reset();

        // beolvassuk

        int i=0;        
        
        argv = (char**)calloc(argc, sizeof(char*));

        while (t.Next(false))
            argv[i++] = arg_strdup(token->c_str());
    }
    catch (...)
    {
        Cleanup();
    }
}


void CCmdlineArgs::Init(int pargc, const char *pargv[])
{
    Cleanup();

    argc = pargc;
    argv = (char**)malloc(argc * sizeof(argv[0]));  

    for (int i=0; i<argc; i++)
        argv[i] = arg_strdup(pargv[i]);
}


void CCmdlineArgs::Cleanup()
{                    
    if (argv)
    {
        for (int i=0; i<argc; i++)
            SFREE(argv[i]);

        free(argv);
        argv = NULL;
    }

    argc = 0;       
}    


const char *CCmdlineArgs::GetValue(const char *arg, const char *default_value) const
{
    int i = Find(arg);

    return (i > 0 && i+1 < argc) ? argv[i+1] : default_value;
}


int CCmdlineArgs::GetIntValue(const char *arg, int default_value, int minvalue, int maxvalue) const
{
    const char *s = GetValue(arg, NULL);
    int ret;

    if (s == NULL || sscanf(s, "%d", &ret) != 1)
        return default_value;

    if (ret < minvalue)
        ret = minvalue;
    else if (ret > maxvalue)
        ret = maxvalue;
    
    return ret;
}


int CCmdlineArgs::Find(const char *arg) const
{
    for (int i=1; i<argc; i++)
    {
        if (strcmp(argv[i], arg) == 0)
            return i;
    }

    return -1;
}
